package com.javafactroy.kunlong.test.db;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.javafactroy.kunlong.DbAgent;
import com.javafactroy.kunlong.api.openfeign.local.ApiDbAgentOpenFeignLocal;
import com.javafactroy.kunlong.api.dto.ApiJob;
import com.javafactroy.kunlong.api.dto.ApiTaskLog;
import com.javafactroy.kunlong.base.annotation.CheckParams;
import com.javafactroy.kunlong.base.config.datasource.JdbcTemplateFactroy;
import com.javafactroy.kunlong.base.model.ReturnPageInfo;
import com.javafactroy.kunlong.base.service.MyService;
import com.javafactroy.kunlong.check.TcheckData;
import com.javafactroy.kunlong.client.feign.dto.ApiResult;
import com.javafactroy.kunlong.common.utils.*;
import com.javafactroy.kunlong.data.entity.mysql.MysqlColumns;
import com.javafactroy.kunlong.codefactroy.iface.ICodeTemplate;
import com.javafactroy.kunlong.codefactroy.iface.IStringTemplate;
import com.javafactroy.kunlong.codefactroy.service.codetemplate.CodeTemplateFactroy;
import com.javafactroy.kunlong.codefactroy.service.base.FileTemplateFactroy;
import com.javafactroy.kunlong.codefactroy.service.stringtemplate.StringTemplate;
import com.javafactroy.kunlong.data.dao.mysql.AttDaysApiMapper;
import com.javafactroy.kunlong.data.dao.mysql.GeneralMysqlSqlMapper;
import com.javafactroy.kunlong.data.dao.mysql.MysqlColumnsMapper;
import com.javafactroy.kunlong.data.dao.mysql.TestMapper;
import com.javafactroy.kunlong.data.dto.TSysUserApiDto;
import com.javafactroy.kunlong.data.entity.AttDaysApiEntity;
import com.javafactroy.kunlong.data.entity.TSysUserApiEntity;
import com.javafactroy.kunlong.data.entity.TaskLogEntity;
import com.javafactroy.kunlong.data.entity.MyBeanDto;
import com.javafactroy.kunlong.data.service.*;
import com.javafactroy.kunlong.base.context.ApiContext;
import com.javafactroy.kunlong.base.metadata.model.TMetadataModel;
import com.javafactroy.kunlong.base.metadata.valueobj.MetadataTable;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

@SpringBootTest(classes = {DbAgent.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SpringExtension.class)
@Slf4j
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.MethodName.class)

public class TestMysql {
    @Autowired
    BeanFactoryUtils beanFactoryUtils;

    @Autowired
    MysqlColumnsMapper mysqlColumnsMapper;

    @Autowired
    TestMapper testMapper;

    @Autowired
    TMetadataModel metadataModel;

    @Autowired
    GeneralMysqlSqlMapper generalSqlMapper;

    @Autowired
    List<ApplicationContext> list;

    @Autowired
    CodeTemplateFactroy codeTemplateFactroy;
    @Autowired
    FileTemplateFactroy fileTemplateFactroy;

    //@Autowired
    //JobRunner jobRunner;


    @Test
    public void test000_queryEmp() throws SQLException {
      //  ReturnPageInfo<EmployeeApiDto> returnPageInfo = employeeApiService.query(new EmployeeApiDto());
      //  log.info("pi = {}",CommonUtils.toJSONString(returnPageInfo));
    }

    @CheckParams
    @Test
    public void test001() throws SQLException {
        Map map = metadataModel.parse(new MyBeanDto());
        log.info("map = {}", CommonUtils.toJSONString(map));

        SqlSessionFactory sessionFactory = ApiContext.INST.getMysqlSessionFactory();

        try (SqlSession session = sessionFactory.openSession()) {

            Connection connection = session.getConnection();
            // 创建Statement对象
            Statement statement = connection.createStatement();
            // 执行SQL查询语句
            String sql = "SELECT * FROM tasklog limit 0";
            ResultSet resultSet = statement.executeQuery(sql);
            // 获取结果集的元数据
            ResultSetMetaData metaData = resultSet.getMetaData();

            com.mysql.cj.jdbc.result.ResultSetMetaData rowSetMetaData = (com.mysql.cj.jdbc.result.ResultSetMetaData) metaData;
            rowSetMetaData.getFields();
            // 获取字段数量
            //int columnCount = metaData.getColumnCount();
            log.info("metadata={}", CommonUtils.toJSONString(metaData));
            resultSet.close();
            statement.close();
            connection.close();
        }

    }

    @Autowired
    @Qualifier("mysqlSessionFactroy")
    SqlSessionFactory sqlSessionFactory;

    @Test
    public void test002() throws Exception {
        SqlSessionFactory sessionFactory = ApiContext.INST.getMysqlSessionFactory();

        SqlSession session = sessionFactory.openSession();
        try {
            GeneralMysqlSqlMapper mapper = session.getMapper(GeneralMysqlSqlMapper.class);
            PageHelper.startPage(1, 2);
            List<TaskLogEntity> t = mapper.selectSql("select * from tasklog ");
            log.info("t = {}", CommonUtils.toJSONString(t));
            log.info("size={}", t.size());
        }finally {

            session.close();
        }

    }


    @Test
    public void test003_selectSql() {

        //  PageHelper.startPage(1, 2);
        List ret = metadataModel.selectMysqlColumns("employee");
        log.info("ret = {}", CommonUtils.toJSONString(ret));
        log.info("size={}", ret.size());
        long selectCount = mysqlColumnsMapper.selectCount(new MysqlColumns());
        log.info("c = {}", selectCount);
    }

    @Test
    public void test004_selectSql() {

        PageHelper.startPage(1, 2);

        List<TaskLogEntity> t = generalSqlMapper.select(new TaskLogEntity().setOprtType(1));
        log.info("t = {}", CommonUtils.toJSONString(t));
        PageInfo<TaskLogEntity> pageInfo = new PageInfo<>(t);

        long total = pageInfo.getTotal();
        log.info("size={},total={}", t.size(), total);

    }

    @Autowired
    RedisApiUtil redisApiUtil;

    //@Autowired
    //SelectModel<TaskLogMap,GeneralSqlMapper> selectModel;
    @Test
    public void test005_selectSql() {

        PageHelper.startPage(1, 1);

        List<TaskLogEntity> t = generalSqlMapper.select(new TaskLogEntity().setOprtType(1));
        log.info("t = {}", CommonUtils.toJSONString(t));
        ReturnPageInfo<TaskLogEntity> apiPageInfo = new ReturnPageInfo<>();
        apiPageInfo.valueOf(t);
        log.info("size={}, total={}", t.size(), apiPageInfo.getTotal());
        redisApiUtil.put("tables", CommonUtils.toJSONString(apiPageInfo));
        log.info("t={}", redisApiUtil.get("tables"));
    }

    public static void main(String[] args) {
        ICodeTemplate i = () -> {
            log.info("111");
            return "";
        };

        IStringTemplate.test();
        Function<String, String> f = a -> a;
        log.info("{}", f.apply("111"));

    }

    @Autowired
    MyService myService;

    //TMetadataModel
    @Test
    public void test006_findMeta() {

        MetadataTable tmetadataTabl = metadataModel.findMetadata("tasklog");
        log.info("tmetadataTabl={}", CommonUtils.toJSONString(tmetadataTabl));
        StrUtil.repeat("1", 299);
        myService.test(new TaskLogEntity().setUser(StrUtil.repeat("中", 90)));
        //log.info(StrUtil.toCamelCase("v_ddd"));
    }

    @Autowired
    StringTemplate stringTemplate;
    @Autowired
    JdbcTemplateFactroy jdbcTemplateFactroy;


    @Test
    public void test007_template() {
        stringTemplate.putParam("${Author}", "leijmdas");
        String text = stringTemplate.parse("d ${Author} is me ${Author} ");
        log.info("text =  {}", text);

    }

    @Autowired
    @Qualifier("mysqlTemplate")
    JdbcTemplate jdbcTemplate;


    @Test
    public void test008_selectMysql() {
        JdbcTemplate template = ApiContext.INST.getMysqlJdbcTemplate();

        PageHelper.startPage(1, 2);
        List<TaskLogEntity> list = jdbcTemplateFactroy.findMysql().query("select * from tasklog",
                new BeanPropertyRowMapper(TaskLogEntity.class));
        log.info("jobs = {}", CommonUtils.toJSONString(list));
        jdbcTemplate.queryForList("select *from tasklog");
    }

    @Test
    public void test009_selectByExample() {
        PageHelper.startPage(1, 3);
        Example example = new Example(TaskLogEntity.class);
        example.createCriteria().andLessThan("id", 10);
        List<TaskLogEntity> taskLogEntities = generalSqlMapper.selectByExample(example);
        log.info("task={}", CommonUtils.toJSONString(taskLogEntities));

    }

    @Autowired
    ApiDbAgentOpenFeignLocal apiDbAgentOpenFeign;

    @Test
    public void test010_selectByOpenFeign() {
        ApiJob apiJob = new ApiJob();
        apiJob.setPageSize(1);
        ApiResult<List<ApiJob>> jobs = apiDbAgentOpenFeign.selectJob(apiJob);
        log.info("jobs = {}", CommonUtils.toJSONString(jobs));

    }

    @Test
    public void test011_selectByOpenFeign() {
        ApiJob jobs = apiDbAgentOpenFeign.sendDemo();

        log.info("jobs = {}", CommonUtils.toJSONString(jobs));
        ApiResult<List<ApiTaskLog>> apiResult = apiDbAgentOpenFeign.selectTaskLog();
        log.info("apiResult = {}", CommonUtils.toJSONString(apiResult));

    }

    @Autowired
    @Qualifier("mysqlSessionTemplate")
    private SqlSessionTemplate sst;

    @Autowired
    AttDaysApiMapper attDaysApiMapper;

    @Test
    public void test012_mysqlSessionTemplate() {
        //  List<Map> list = sst.selectList("select * from t_sys_user");
        PageHelper.startPage(1, 2);
        List<AttDaysApiEntity> list = attDaysApiMapper.query(new AttDaysApiEntity());
        log.info("{}", CommonUtils.toJSONString(list));
    }



    @Autowired
    TSysUserService sysUserService;

    @Test
    public void test014_mysqlService() {
        TSysUserApiEntity param = new TSysUserApiEntity();
        param.like("mobileNo", "186");
        //  query.notBetween("id", "1"); query.eq("opBy",-1);
        // query.betweenDate("createOn","2015-12-02 00:00:00","2015-12-02 00:00:00");
        param.between("createOn", "2015-12-02 00:00:00", "2015-12-02 00:00:00");

        ReturnPageInfo<TSysUserApiEntity> list = sysUserService.query(param);
        log.info("{}", CommonUtils.toJSONString(list));
        log.info("param={}", CommonUtils.toJSONString(param));
    }

    @Autowired
    TSysUserApiService sysUserDtoService;

    @Test
    public void test015_mysqlService() {
        TSysUserApiDto param = new TSysUserApiDto();
        param.like("mobileNo", "186");
        param.in("orgId", "1");
        //  param.notBetween("id", "1"); query.eq("opBy",-1);
        param.betweenDate("createOn", "2015-12-02 00:00:00", "2015-12-02 00:00:00");
        // param.between("createOn", "2015-12-02 00:00:00", "2015-12-02 00:00:00");

        ReturnPageInfo<TSysUserApiDto> list = sysUserDtoService.query(param);
        log.info("{}", CommonUtils.toJSONString(list));

    }


    @Test
    public void test016_mysqlService() {
//        DepartmentApiDto departmentApiDto=new DepartmentApiDto();
//        departmentApiDto.setPageSize(12);
//        ReturnPageInfo apiPageInfo = departmentService.query(departmentApiDto);
//        log.info("page={}", CommonUtils.toJSONString(apiPageInfo));
//       TGeneralData<DepartmentApiDto> data=new TGeneralData<>();
//       data.setList(apiPageInfo.getList());
//       data.split2Group();
//       log.info("{}",data);

    }

    @Autowired
    TcheckData tcheckData;
    @Test
    public void test017_mysqlService() {
//        DepartmentApiEntity entity = departmentService.selectByPkey(1l);
//        log.info("page={}", CommonUtils.toJSONString(entity));
//        tcheckData.check(entity,"id=1|code=61");
    }

    @Test
    void test018_Future1() throws ExecutionException, InterruptedException {
        ExecutorService delegate = Executors.newFixedThreadPool(5);
        try {
            ListeningExecutorService executorService = MoreExecutors.listeningDecorator(delegate);
            //异步执行一个任务
            ListenableFuture<Integer> submit = executorService.submit(() -> {
                log.info("{}", System.currentTimeMillis());
                //休眠2秒，默认耗时
                TimeUnit.SECONDS.sleep(2);
                log.info("{}", System.currentTimeMillis());
                return 10;
            });
            //当任务执行完毕之后回调对应的方法
            submit.addListener(() -> {
                log.info("任务执行完毕了，我被回调了");
            }, MoreExecutors.directExecutor());
            log.info("{}", submit.get());
        } finally {
            delegate.shutdown();
        }
    }

    @Autowired
    ExcelExportService excelExportService;
    @Test
    public void Test019_exportExls() throws IOException {

        TSysUserApiEntity param = new TSysUserApiEntity();

        ReturnPageInfo<TSysUserApiEntity> apiPageInfo = sysUserService.query(param);
        log.info("{}", CommonUtils.toJSONString(apiPageInfo));
        log.info("param={}", CommonUtils.toJSONString(param));
        ExcelExportDto<TSysUserApiEntity> excelExportDto = new ExcelExportDto<>();
        excelExportDto.setFileName(StrUtil.format("/opt/user{}.xlsx", System.currentTimeMillis()));
        excelExportDto.setSheetName("user");
        excelExportDto.setRecords(apiPageInfo.getList());
        excelExportService.exportXls(excelExportDto);
    }
}
